package com.zh.opcua.milo;

import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
import org.eclipse.milo.opcua.sdk.client.api.nodes.Node;
import org.eclipse.milo.opcua.sdk.client.api.nodes.VariableNode;
import org.eclipse.milo.opcua.sdk.client.api.subscriptions.UaMonitoredItem;
import org.eclipse.milo.opcua.stack.core.Identifiers;
import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue;
import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
import org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode;
import org.eclipse.milo.opcua.stack.core.types.builtin.Variant;
import org.eclipse.milo.opcua.stack.core.types.enumerated.TimestampsToReturn;
import org.eclipse.milo.opcua.stack.core.types.structured.DiscoveryConfiguration;
import org.eclipse.milo.opcua.stack.core.types.structured.EndpointDescription;

import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * Copyright (C) 广州中和互联网技术有限公司
 *
 * @author 范家微 fanjiawei@borche.cn
 * @date :2020/12/17 18:47
 */
public class MiloDemo {
	public static void main(String[] args) throws Exception {
		OpcUaClient opcUaClient = OPCUAClientUtils.createOpcUaClient();
		System.out.println(opcUaClient);
		String endpointUrl = opcUaClient.getConfig().getEndpoint().get().getEndpointUrl();
		endpointUrl.substring(endpointUrl.lastIndexOf('/') + 1, endpointUrl.lastIndexOf(':'));
		//浏览一个节点:
		//开启同步连接
		opcUaClient.connect().get();
		opcUaClient.connect().get();
		opcUaClient.connect().get();
		opcUaClient.connect().get();
		opcUaClient.connect().get();
		NodeId nodeId1 = new NodeId(1, "barrelTemp4");


		VariableNode vnode = opcUaClient.getAddressSpace().createVariableNode(nodeId1);
		DataValue value2 = vnode.readValue().get();

		Variant variant2 = value2.getValue();

		variant2.getValue().toString();

		CompletableFuture<DataValue> future6 = opcUaClient.readValue(0.0, TimestampsToReturn.Both, nodeId1);
		String s = future6.get().getValue().getValue().toString();
		System.out.println(s);


		//浏览根节点
		List<Node> nodes = opcUaClient.getAddressSpace().browse(Identifiers.RootFolder).get();
		String[] strings = opcUaClient.getNamespaceTable().toArray();
		for (String string : strings) {
			System.out.println(string);
		}

//		for (int i = 0; i < 100000000; i++) {
//			//读取值通道2
//			//NodeId nodeId_Tag1 = new NodeId(1, 50442);
//			NodeId nodeId_Tag1 = new NodeId(1, 50361);
//			DataValue dataValue2 = opcUaClient.getAddressSpace().createVariableNode(nodeId_Tag1).readValue().get();
//			dataValue2.getValue().getValue();
//			Object value1 = opcUaClient.readValue(0.0, TimestampsToReturn.Both, nodeId_Tag1).get().getValue().getValue();
//			System.out.println(value1.toString());
//		}

		/**
		 * 查询所有服务端内置节点和类名
		 */
		opcUaClient.getDataTypeManager().getTypeDictionary("http://opcfoundation.org/UA/");

		for (Node node : nodes) {
			System.out.println(node);
			System.out.println("命名空间" + node.getNodeId().get().getNamespaceIndex());
			System.out.println("识别码" + node.getNodeId().get().getIdentifier());
			System.out.println("Node= " + node.getBrowseName().get().getName());
			System.out.println("------浏览对象------");
			System.out.println(node.getBrowseName().get().getName());
			System.out.println(node.getBrowseName().get().getNamespaceIndex());
			System.out.println("-----描述对象-------");
			System.out.println(node.getDescription().get().getText());
			System.out.println(node.getDescription().get().getLocale());
			System.out.println("------显示对象------");
			System.out.println(node.getDisplayName().get().getText());
			System.out.println(node.getDisplayName().get().getLocale());
			System.out.println("---------NodeClass-------");
			System.out.println(node.getNodeClass().get().getValue());
			System.out.println("---------UserWriteMask-------");
			System.out.println(node.getUserWriteMask().get().longValue());
			System.out.println(node.getUserWriteMask().get().doubleValue());
			System.out.println(node.getUserWriteMask().get().intValue());
			System.out.println("---------WriteMask-------");
			System.out.println(node.getWriteMask().get().longValue());
			System.out.println(node.getWriteMask().get().doubleValue());
			System.out.println(node.getWriteMask().get().intValue());
			break;


		}


//		for (int i = 0; i < 100000000; i++) {
//			NodeId stringNode = new NodeId(1, 50442);
//
//
//			CompletableFuture<DataValue> future = opcUaClient.readValue(0.0, TimestampsToReturn.Both, stringNode);
//			future.get().getStatusCode().isGood();
//			String string66 = future.get().getValue().getValue().toString();
//			System.out.println(string66);
//
//		}
		//写数据
		// 1.创建节点
		//NodeId stringNode = new NodeId(1, 50235);
		NodeId stringNode = new NodeId(1, 50240);

		//Integer integer = new Integer(4);
		int a = 4;
		//String string = new String("fdsfsfa");
		// 2.创建Variant对象和DataValue对象
		Variant variant = new Variant(a);
		//Variant variant1 = new Variant(string);
		// 不要写状态或时间戳
		DataValue dataValue1 = new DataValue(variant, null, null);
		// 3.获取返回状态
		StatusCode statusCode = opcUaClient.writeValue(stringNode, dataValue1).get();
		System.out.println(statusCode.isGood());
		// 4.获取新增的值
		CompletableFuture<DataValue> future = opcUaClient.readValue(0.0, TimestampsToReturn.Both, stringNode);
		future.get().getStatusCode().isGood();
		String string66 = future.get().getValue().getValue().toString();
		System.out.println(string66);


		// 读取时间,Identifiers.Server_ServerStatus_StartTime内置NodeId对象
		CompletableFuture<VariableNode> node = opcUaClient.getAddressSpace().getVariableNode(Identifiers.Server_ServerStatus_StartTime);
		Object value = node.get().readValue().get().getValue().getValue();
		System.out.println(value);

		NodeId nodeId = new NodeId(1, "50442");
		//调用get()方法来阻塞等待方法返回
		DataValue dataValue = opcUaClient.readValue(0.0, TimestampsToReturn.Both, nodeId).get();
		System.out.println("读取到的值：" + dataValue.getValue().getValue().toString());


//
//		//写数据
//		// 1.创建节点
//		NodeId stringNode = new NodeId(2, "通道 2.设备 1.TAG5");
//
//		// 2.创建Variant对象和DataValue对象
//		Variant variant = new Variant("今天天气不好");
//		// 不要写状态或时间戳
//		DataValue dataValue1 = new DataValue(variant, null, null);
//		// 3.获取返回状态
//		StatusCode statusCode = opcUaClient.writeValue(stringNode, dataValue1).get();
//		System.out.println(statusCode.isGood());
//		// 4.获取新增的值
//		CompletableFuture<DataValue> future = opcUaClient.readValue(0.0, TimestampsToReturn.Both, stringNode);
//		String string = future.get().getValue().getValue().toString();
//		System.out.println(string);


		// 创建变量的订阅
		List<UaMonitoredItem> items = MiloSubscribe.createSubscription(opcUaClient);
	}
}
